home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 April: Mac OS SDK / Dev.CD Apr 97 SDK1.toast / Development Kits (Disc 1) / Interfaces&Libraries / Interfaces / CIncludes / PEFBinaryFormat.h < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-11  |  49.2 KB  |  1,064 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        PEFBinaryFormat.h
  3.  
  4.      Contains:    PEF Types and Macros
  5.  
  6.      Version:    Technology:    System 7.5
  7.                  Package:    Universal Interfaces 2.1.4
  8.  
  9.      Copyright:    © 1984-1996 by Apple Computer, Inc.
  10.                  All rights reserved.
  11.  
  12.      Bugs?:        If you find a problem with this file, use the Apple Bug Reporter
  13.                  stack.  Include the file and version information (from above)
  14.                  in the problem description and send to:
  15.                      Internet:    apple.bugs@applelink.apple.com
  16.                      AppleLink:    APPLE.BUGS
  17. */
  18.  
  19. #ifndef __PEFBINARYFORMAT__
  20. #define __PEFBINARYFORMAT__
  21.  
  22. #ifndef __TYPES__
  23. #include <Types.h>
  24. #endif
  25.  
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif
  29.  
  30. #if PRAGMA_IMPORT_SUPPORTED
  31. #pragma import on
  32. #endif
  33.  
  34. #if PRAGMA_ALIGN_SUPPORTED
  35. #pragma options align=mac68k
  36. #endif
  37.  
  38.  
  39. /* -----------------------------------------------------------------------------------------    */
  40. /* Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    */
  41. /* 10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        */
  42. /* packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        */
  43. /* ensure consistent treatment across compilers.                                                */
  44.  
  45.  
  46. /* ======================================================================================== */
  47. /* Overall Structure */
  48. /* ================= */
  49.  
  50.  
  51. /* -------------------------------------------------------------------------------------------    */
  52. /* This header contains a complete set of types and macros for dealing with the PEF executable    */
  53. /* format.  While some description is provided, this header is not meant as a primary source    */
  54. /* of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    */
  55. /* Runtime Architectures book.  This header is primarily a physical format description.  Thus    */
  56. /* it depends on as few other headers as possible and structure fields have obvious sizes.        */
  57. /*                                                                                                 */
  58. /* The physical storage for a PEF executable is known as a "container".  This refers to just    */
  59. /* the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    */
  60. /* data fork, that one data fork has five containers within it.                                    */
  61. /*                                                                                                 */
  62. /* A PEF container consists of an overall header, followed by one or more section headers,        */
  63. /* followed by the section name table, followed by the contents for the sections.  Some kinds    */
  64. /* of sections have specific internal representation.  The "loader" section is the most common    */
  65. /* of these special sections.  It contains information on the exports, imports, and runtime        */
  66. /* relocations required to prepare the executable.  PEF containers are self contained, all        */
  67. /* portions are located via relative offsets.                                                    */
  68. /*                                                                                                 */
  69. /*                                                                                                 */
  70. /*            +-------------------------------+                                                    */
  71. /*            |        Container Header        |    40 bytes                                        */
  72. /*            +-------------------------------+                                                    */
  73. /*            |        Section 0 header        |    28 bytes each                                    */
  74. /*            |...............................|                                                    */
  75. /*            |            - - - -                |                                                    */
  76. /*            |...............................|                                                    */
  77. /*            |        Section n-1 header        |                                                    */
  78. /*            +-------------------------------+                                                    */
  79. /*            |        Section Name Table        |                                                    */
  80. /*            +-------------------------------+                                                    */
  81. /*            |        Section x raw data        |                                                    */
  82. /*            +-------------------------------+                                                    */
  83. /*             |            - - - -                |                                                    */
  84. /*            +-------------------------------+                                                    */
  85. /*            |        Section y raw data        |                                                    */
  86. /*            +-------------------------------+                                                    */
  87. /*                                                                                                 */
  88. /*                                                                                                 */
  89. /* The sections are implicitly numbered from 0 to n according to the order of their headers.    */
  90. /* The headers of the instantiated sections must precede those of the non-instantiated            */
  91. /* sections.  The ordering of the raw data is independent of the section header ordering.        */
  92. /* Each section header contains the offset for that section's raw data.                            */
  93.  
  94.  
  95. /* =========================================================================================== */
  96. /* Container Header */
  97. /* ================ */
  98.  
  99.  
  100. struct PEFContainerHeader {
  101.     OSType                             tag1;                        /* Must contain 'Joy!'. */
  102.     OSType                             tag2;                        /* Must contain 'peff'.  (Yes, with two 'f's.) */
  103.     OSType                             architecture;                /* The ISA for code sections.  Constants in CodeFragments.h. */
  104.     UInt32                             formatVersion;                /* The physical format version. */
  105.     UInt32                             dateTimeStamp;                /* Macintosh format creation/modification stamp. */
  106.     UInt32                             oldDefVersion;                /* Old definition version number for the code fragment. */
  107.     UInt32                             oldImpVersion;                /* Old implementation version number for the code fragment. */
  108.     UInt32                             currentVersion;                /* Current version number for the code fragment. */
  109.     UInt16                             sectionCount;                /* Total number of section headers that follow. */
  110.     UInt16                             instSectionCount;            /* Number of instantiated sections. */
  111.     UInt32                             reservedA;                    /* Reserved, must be written as zero. */
  112. };
  113. typedef struct PEFContainerHeader PEFContainerHeader;
  114.  
  115.  
  116. enum {
  117.     kPEFTag1                    = 'Joy!',                        /* For non-Apple compilers: 0x4A6F7921. */
  118.     kPEFTag2                    = 'peff',                        /* For non-Apple compilers: 0x70656666. */
  119.     kPEFVersion                    = 0x00000001
  120. };
  121.  
  122.  
  123. enum {
  124.     kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader)
  125. };
  126.  
  127. #define PEFFirstSectionNameOffset(container)    \
  128.             ( kPEFFirstSectionHeaderOffset + ((container)->sectionCount * sizeof ( PEFSectionHeader )) )
  129.  
  130.  
  131. /* =========================================================================================== */
  132. /* Section Headers */
  133. /* =============== */
  134.  
  135.  
  136. struct PEFSectionHeader {
  137.     SInt32                             nameOffset;                    /* Offset of name within the section name table, -1 => none. */
  138.     UInt32                             defaultAddress;                /* Default address, affects relocations. */
  139.     UInt32                             totalLength;                /* Fully expanded size in bytes of the section contents. */
  140.     UInt32                             unpackedLength;                /* Size in bytes of the "initialized" part of the contents. */
  141.     UInt32                             containerLength;            /* Size in bytes of the raw data in the container. */
  142.     UInt32                             containerOffset;            /* Offset of section's raw data. */
  143.     UInt8                             sectionKind;                /* Kind of section contents/usage. */
  144.     UInt8                             shareKind;                    /* Sharing level, if a writeable section. */
  145.     UInt8                             alignment;                    /* Preferred alignment, expressed as log 2. */
  146.     UInt8                             reservedA;                    /* Reserved, must be zero. */
  147. };
  148. typedef struct PEFSectionHeader PEFSectionHeader;
  149.  
  150.  
  151. enum {
  152.                                                                 /* Values for the sectionKind field. */
  153.                                                                 /*    Section kind values for instantiated sections. */
  154.     kPEFCodeSection                = 0,                            /* Code, presumed pure & position independent. */
  155.     kPEFUnpackedDataSection        = 1,                            /* Unpacked writeable data. */
  156.     kPEFPackedDataSection        = 2,                            /* Packed writeable data. */
  157.     kPEFConstantSection            = 3,                            /* Read-only data. */
  158.     kPEFExecDataSection            = 6,                            /* Intermixed code and writeable data. */
  159.                                                                 /* Section kind values for non-instantiated sections. */
  160.     kPEFLoaderSection            = 4,                            /* Loader tables. */
  161.     kPEFDebugSection            = 5,                            /* Reserved for future use. */
  162.     kPEFExceptionSection        = 7,                            /* Reserved for future use. */
  163.     kPEFTracebackSection        = 8                                /* Reserved for future use. */
  164. };
  165.  
  166.  
  167. enum {
  168.                                                                 /* Values for the shareKind field. */
  169.     kPEFProcessShare            = 1,                            /* Shared within a single process. */
  170.     kPEFGlobalShare                = 4,                            /* Shared across the entire system. */
  171.     kPEFProtectedShare            = 5                                /* Readable across the entire system, writeable only to privileged code. */
  172. };
  173.  
  174.  
  175.  
  176. /* =========================================================================================== */
  177. /* Packed Data Contents */
  178. /* ==================== */
  179.  
  180.  
  181. /* -------------------------------------------------------------------------------------------    */
  182. /* The raw contents of a packed data section are a sequence of byte codes.  The basic format    */
  183. /* has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        */
  184. /* counts larger than 31, and to contain a second or third count.  Further additional bytes        */
  185. /* contain actual data values to transfer.                                                        */
  186. /*                                                                                                 */
  187. /* All counts are represented in a variable length manner.  A zero in the initial 5 bit count    */
  188. /* indicates the actual value follows.  In this case, and for the second and third counts, the    */
  189. /* count is represented as a variable length sequence of bytes.  The bytes are stored in big    */
  190. /* endian manner, most significant part first.  The high order bit is set in all but the last    */
  191. /* byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    */
  192. /* low order 7 bits of the next byte.                                                            */
  193.  
  194.  
  195. enum {
  196.                                                                 /* The packed data opcodes. */
  197.     kPEFPkDataZero                = 0,                            /* Zero fill "count" bytes. */
  198.     kPEFPkDataBlock                = 1,                            /* Block copy "count" bytes. */
  199.     kPEFPkDataRepeat            = 2,                            /* Repeat "count" bytes "count2"+1 times. */
  200.     kPEFPkDataRepeatBlock        = 3,                            /* Interleaved repeated and unique data. */
  201.     kPEFPkDataRepeatZero        = 4                                /* Interleaved zero and unique data. */
  202. };
  203.  
  204.  
  205. enum {
  206.     kPEFPkDataOpcodeShift        = 5,
  207.     kPEFPkDataCount5Mask        = 0x1F,
  208.     kPEFPkDataMaxCount5            = 31,
  209.     kPEFPkDataVCountShift        = 7,
  210.     kPEFPkDataVCountMask        = 0x7F,
  211.     kPEFPkDataVCountEndMask        = 0x80
  212. };
  213.  
  214. #define PEFPkDataOpcode(byte) ( ((UInt8)(byte)) >> kPEFPkDataOpcodeShift )
  215.  
  216. #define PEFPkDataCount5(byte) ( ((UInt8)(byte)) & kPEFPkDataCount5Mask )
  217.  
  218. #define PEFPkDataComposeInstr(opcode,count5)        \
  219.             ( (((UInt8)(opcode)) << kPEFPkDataOpcodeShift) | ((UInt8)(count5)) )
  220.  
  221.  
  222. /* ------------------------------------------------------------------------------------------    */
  223. /* The following code snippet can be used to input a variable length count.                        */
  224. /*                                                                                                 */
  225. /*        count = 0;                                                                                */
  226. /*        do {                                                                                    */
  227. /*            byte = *bytePtr++;                                                                    */
  228. /*            count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            */
  229. /*        } while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        */
  230. /*                                                                                                 */
  231. /* The following code snippet can be used to output a variable length count to a byte array.    */
  232. /* This is more complex than the input code because the chunks are output in big endian order.    */
  233. /* Think about handling values like 0 or 0x030000.                                                */
  234. /*                                                                                                 */
  235. /*        count = 1;.                                                                                */
  236. /*        tempValue = value >> kPEFPkDataCountShift;                                                */
  237. /*        while ( tempValue != 0 ) {                                                                */
  238. /*            count += 1;                                                                            */
  239. /*            tempValue = tempValue >> kPEFPkDataCountShift;                                        */
  240. /*        }                                                                                        */
  241. /*                                                                                                 */
  242. /*        bytePtr += count;                                                                        */
  243. /*        tempPtr = bytePtr - 1;                                                                    */
  244. /*        *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        */
  245. /*        for ( count -= 1; count != 0; count -= 1 ) {                                            */
  246. /*            value = value >> kPEFPkDataCountShift;                                                */
  247. /*            *tempPtr-- = value | kPEFPkDataCountEndMask;                                        */
  248. /*        }                                                                                        */
  249.  
  250.  
  251. /* =========================================================================================== */
  252. /* Loader Section */
  253. /* ============== */
  254.  
  255.  
  256. /* ------------------------------------------------------------------------------------------    */
  257. /* The loader section contains information needed to prepare the code fragment for execution.    */
  258. /* This includes this fragment's exports, the import libraries and the imported symbols from    */
  259. /* each library, and the relocations for the writeable sections.                                */
  260. /*                                                                                                 */
  261. /*            +-----------------------------------+                <-- containerOffset --------+    */
  262. /*            |        Loader Info Header            |    56 bytes                                |    */
  263. /*            |-----------------------------------|                                            |    */
  264. /*            |        Imported Library 0            |    24 bytes each                            |    */
  265. /*            |...................................|                                            |    */
  266. /*            |            - - -                    |                                            |    */
  267. /*            |...................................|                                            |    */
  268. /*            |        Imported Library l-1        |                                            |    */
  269. /*            |-----------------------------------|                                            |    */
  270. /*            |        Imported Symbol 0            |    4 bytes each                            |    */
  271. /*            |...................................|                                            |    */
  272. /*            |            - - -                    |                                            |    */
  273. /*            |...................................|                                            |    */
  274. /*            |         Imported Symbol i-1            |                                            |    */
  275. /*            |-----------------------------------|                                            |    */
  276. /*            |        Relocation Header 0            |    12 bytes each                            |    */
  277. /*            |...................................|                                            |    */
  278. /*            |            - - -                    |                                            |    */
  279. /*            |...................................|                                            |    */
  280. /*            |        Relocation Header r-1        |                                            |    */
  281. /*            |-----------------------------------|                <-- + relocInstrOffset -----|    */
  282. /*            |        Relocation Instructions        |                                            |    */
  283. /*            |-----------------------------------|                <-- + loaderStringsOffset --|    */
  284. /*            |        Loader String Table            |                                            |    */
  285. /*            |-----------------------------------|                <-- + exportHashOffset -----+    */
  286. /*            |        Export Hash Slot 0            |    4 bytes each                                */
  287. /*            |...................................|                                                */
  288. /*            |            - - -                    |                                                */
  289. /*            |...................................|                                                */
  290. /*            |         Export Hash Slot h-1        |                                                */
  291. /*            |-----------------------------------|                                                */
  292. /*            |        Export Symbol Key 0            |    4 bytes each                                */
  293. /*            |...................................|                                                */
  294. /*            |            - - -                    |                                                */
  295. /*            |...................................|                                                */
  296. /*            |        Export Symbol Key e-1        |                                                */
  297. /*            |-----------------------------------|                                                */
  298. /*            |        Export Symbol 0                |    10 bytes each                                */
  299. /*            |...................................|                                                */
  300. /*            |            - - -                    |                                                */
  301. /*            |...................................|                                                */
  302. /*            |        Export Symbol e-1            |                                                */
  303. /*            +-----------------------------------+                                                */
  304.  
  305.  
  306. struct PEFLoaderInfoHeader {
  307.     SInt32                             mainSection;                /* Section containing the main symbol, -1 => none. */
  308.     UInt32                             mainOffset;                    /* Offset of main symbol. */
  309.     SInt32                             initSection;                /* Section containing the init routine's TVector, -1 => none. */
  310.     UInt32                             initOffset;                    /* Offset of the init routine's TVector. */
  311.     SInt32                             termSection;                /* Section containing the term routine's TVector, -1 => none. */
  312.     UInt32                             termOffset;                    /* Offset of the term routine's TVector. */
  313.     UInt32                             importedLibraryCount;        /* Number of imported libraries.  ('l') */
  314.     UInt32                             totalImportedSymbolCount;    /* Total number of imported symbols.  ('i') */
  315.     UInt32                             relocSectionCount;            /* Number of sections with relocations.  ('r') */
  316.     UInt32                             relocInstrOffset;            /* Offset of the relocation instructions. */
  317.     UInt32                             loaderStringsOffset;        /* Offset of the loader string table. */
  318.     UInt32                             exportHashOffset;            /* Offset of the export hash table. */
  319.     UInt32                             exportHashTablePower;        /* Export hash table size as log 2.  (Log2('h')) */
  320.     UInt32                             exportedSymbolCount;        /* Number of exported symbols.  ('e') */
  321. };
  322. typedef struct PEFLoaderInfoHeader PEFLoaderInfoHeader;
  323.  
  324.  
  325.  
  326. /* =========================================================================================== */
  327. /* Imported Libraries */
  328. /* ------------------ */
  329.  
  330.  
  331. struct PEFImportedLibrary {
  332.     UInt32                             nameOffset;                    /* Loader string table offset of library's name. */
  333.     UInt32                             oldImpVersion;                /* Oldest compatible implementation version. */
  334.     UInt32                             currentVersion;                /* Current version at build time. */
  335.     UInt32                             importedSymbolCount;        /* Imported symbol count for this library. */
  336.     UInt32                             firstImportedSymbol;        /* Index of first imported symbol from this library. */
  337.     UInt8                             options;                    /* Option bits for this library. */
  338.     UInt8                             reservedA;                    /* Reserved, must be zero. */
  339.     UInt16                             reservedB;                    /* Reserved, must be zero. */
  340. };
  341. typedef struct PEFImportedLibrary PEFImportedLibrary;
  342.  
  343.  
  344. enum {
  345.                                                                 /* Bits for the PEFImportedLibrary options field. */
  346.     kPEFWeakImportLibMask        = 0x40,                            /* The imported library is allowed to be missing. */
  347.     kPEFInitLibBeforeMask        = 0x80                            /* The imported library must be initialized first. */
  348. };
  349.  
  350.  
  351.  
  352. /* =========================================================================================== */
  353. /* Imported Symbols */
  354. /* ---------------- */
  355.  
  356.  
  357. /* -------------------------------------------------------------------------------------------    */
  358. /* The PEFImportedSymbol type has the following bit field layout.                                */
  359. /*                                                                                                 */
  360. /*                                                                       3                        */
  361. /*         0             7 8                                             1                        */
  362. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  363. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  364. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  365. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  366.  
  367.  
  368. struct PEFImportedSymbol {
  369.     UInt32                             classAndName;
  370. };
  371. typedef struct PEFImportedSymbol PEFImportedSymbol;
  372.  
  373.  
  374. enum {
  375.     kPEFImpSymClassShift        = 24,
  376.     kPEFImpSymNameOffsetMask    = 0x00FFFFFF,
  377.     kPEFImpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215 */
  378. };
  379.  
  380. #define PEFImportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFImpSymClassShift))
  381. #define PEFImportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFImpSymNameOffsetMask)
  382.  
  383. #define PEFComposeImportedSymbol(class,nameOffset)        \
  384.             ( ( ((UInt32)(class)) << kPEFImpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  385.  
  386. enum {
  387.                                                                 /* Imported and exported symbol classes. */
  388.     kPEFCodeSymbol                = 0x00,
  389.     kPEFDataSymbol                = 0x01,
  390.     kPEFTVectorSymbol            = 0x02,
  391.     kPEFTOCSymbol                = 0x03,
  392.     kPEFGlueSymbol                = 0x04,
  393.     kPEFUndefinedSymbol            = 0x0F,
  394.     kPEFWeakImportSymMask        = 0x80
  395. };
  396.  
  397.  
  398.  
  399. /* =========================================================================================== */
  400. /* Exported Symbol Hash Table */
  401. /* -------------------------- */
  402.  
  403.  
  404. /* -------------------------------------------------------------------------------------------    */
  405. /* Exported symbols are described in four parts, optimized for speed of lookup.  These parts    */
  406. /* are the "export hash table", the "export key table", the "export symbol table", and the        */
  407. /* "export name table".  Overall they contain a flattened representation of a fairly normal        */
  408. /* hashed symbol table.                                                                            */
  409. /*                                                                                                */
  410. /* The export hash table is an array of small fixed size elements.  The number of elements is    */
  411. /* a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    */
  412. /* Each hash slot contains a count of the number of exported symbols that map to this slot and    */
  413. /* the index of the first of those symbols in the key and symbol tables.  Of course some hash    */
  414. /* slots will have a zero count.                                                                */
  415. /*                                                                                                */
  416. /* The key and symbol tables are also arrays of fixed size elements, one for each exported        */
  417. /* symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        */
  418. /* slot are contiguous.  The key table contains just the full 32 bit hash word for each            */
  419. /* exported symbol.  The symbol table contains the offset of the symbol's name in the string    */
  420. /* table and other information about the exported symbol.                                        */
  421. /*                                                                                                */
  422. /* To look up an export you take the hashword and compute the hash slot index.  You then scan    */
  423. /* the indicated portion of the key table for matching hashwords.  If a hashword matches, you    */
  424. /* look at the corresponding symbol table entry to find the full symbol name.  If the names        */
  425. /* match the symbol is found.                                                                    */
  426.  
  427.  
  428. /* -------------------------------------------------------------------------------------------    */
  429. /* The following function may be used to compute the hash table size.  Signed values are used    */
  430. /* just to avoid potential code generation overhead for unsigned division.                        */
  431. /*                                                                                                 */
  432. /*        UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            */
  433. /*        {                                                                                        */
  434. /*            SInt32    exponent;                                                                    */
  435. /*                                                                                                 */
  436. /*            const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    */
  437. /*            const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    */
  438. /*                                                                                                 */
  439. /*            for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) {                    */
  440. /*                if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                */
  441. /*            }                                                                                    */
  442. /*                                                                                                 */
  443. /*            return exponent;                                                                    */
  444. /*                                                                                                 */
  445. /*        }    // PEFComputeHashTableExponent ()                                                    */
  446.  
  447.  
  448. /* -------------------------------------------------------------------------------------------    */
  449. /* The PEFExportedSymbolHashSlot type has the following bit field layout.                        */
  450. /*                                                                                                 */
  451. /*                                   1 1                                 3                        */
  452. /*         0                         3 4                                 1                        */
  453. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  454. /*        | symbol count              | index of first export key         |                        */
  455. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  456. /*        |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        */
  457.  
  458.  
  459. struct PEFExportedSymbolHashSlot {
  460.     UInt32                             countAndStart;
  461. };
  462. typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot;
  463.  
  464.  
  465. enum {
  466.     kPEFHashSlotSymCountShift    = 18,
  467.     kPEFHashSlotFirstKeyMask    = 0x0003FFFF,
  468.     kPEFHashSlotMaxSymbolCount    = 0x00003FFF,                    /*  16,383 */
  469.     kPEFHashSlotMaxKeyIndex        = 0x0003FFFF                    /* 262,143 */
  470. };
  471.  
  472. #define PEFHashTableIndex(fullHashWord,hashTablePower)    \
  473.             ( ( (fullHashWord) ^ ((fullHashWord) >> (hashTablePower)) ) & ((1 << (hashTablePower)) - 1) )
  474.  
  475. #define PEFHashSlotSymbolCount(countAndStart)    ((UInt32) ((countAndStart) >> kPEFHashSlotSymCountShift))
  476. #define PEFHashSlotFirstKey(countAndStart)        ((countAndStart) & kPEFHashSlotFirstKeyMask)
  477.  
  478. #define PEFComposeExportedSymbolHashSlot(symbolCount,firstKey)    \
  479.             ( ( ((UInt32)(symbolCount)) << kPEFHashSlotSymCountShift ) | ( (UInt32)(firstKey) ) )
  480.  
  481.  
  482. /* =========================================================================================== */
  483. /* Exported Symbol Hash Key */
  484. /* ------------------------ */
  485.  
  486.  
  487. struct PEFSplitHashWord {
  488.     UInt16                             nameLength;
  489.     UInt16                             hashValue;
  490. };
  491. typedef struct PEFSplitHashWord PEFSplitHashWord;
  492.  
  493. struct PEFExportedSymbolKey {
  494.     union {
  495.         UInt32                             fullHashWord;
  496.         PEFSplitHashWord                 splitHashWord;
  497.     }                                 u;
  498. };
  499. typedef struct PEFExportedSymbolKey PEFExportedSymbolKey;
  500.  
  501.  
  502. enum {
  503.     kPEFHashLengthShift            = 16,
  504.     kPEFHashValueMask            = 0x0000FFFF,
  505.     kPEFHashMaxLength            = 0x0000FFFF                    /* 65,535 */
  506. };
  507.  
  508. #define PEFHashNameLength(fullHashWord)    ((UInt32) ((fullHashWord) >> kPEFHashLengthShift))
  509. #define PEFHashValue(fullHashWord)    ((fullHashWord) & kPEFHashValueMask)
  510.  
  511. #define PEFComposeFullHashWord(nameLength,hashValue)    \
  512.             ( ( ((UInt32)(nameLength)) << kPEFHashLengthShift ) | ( (UInt32)(hashValue) ) )
  513.  
  514.  
  515. /* -------------------------------------------------------------------------------------------            */
  516. /* The following function computes the full 32 bit hash word.                                            */
  517. /*                                                                                                         */
  518. /*        UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    */
  519. /*                                      UInt32    nameLength )    // ! The text may be zero terminated.    */
  520. /*        {                                                                                                */
  521. /*            BytePtr    charPtr        = nameText;                                                                */
  522. /*            SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                */
  523. /*            UInt32    length        = 0;                                                                    */
  524. /*            UInt32    limit;                                                                                */
  525. /*            UInt32    result;                                                                                */
  526. /*            UInt8    currChar;                                                                            */
  527. /*                                                                                                         */
  528. /*            #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    */
  529. /*                                                                                                         */
  530. /*            for ( limit = nameLength; limit > 0; limit -= 1 ) {                                            */
  531. /*                currChar = *charPtr++;                                                                    */
  532. /*                if ( currChar == NULL ) break;                                                            */
  533. /*                length += 1;                                                                            */
  534. /*                hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        */
  535. /*            }                                                                                            */
  536. /*                                                                                                         */
  537. /*            result    = (length << kPEFHashLengthShift) |                                                    */
  538. /*                      ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    */
  539. /*                                                                                                         */
  540. /*            return result;                                                                                */
  541. /*                                                                                                         */
  542. /*        }    // PEFComputeHashWord ()                                                                    */
  543.  
  544.  
  545. /* =========================================================================================== */
  546. /* Exported Symbols */
  547. /* ---------------- */
  548.  
  549.  
  550. struct PEFExportedSymbol {                                                                /* ! This structure is 10 bytes long and arrays are packed. */
  551.     UInt32                             classAndName;                /* A combination of class and name offset. */
  552.     UInt32                             symbolValue;                /* Typically the symbol's offset within a section. */
  553.     SInt16                             sectionIndex;                /* The index of the section, or pseudo-section, for the symbol. */
  554. };
  555. typedef struct PEFExportedSymbol PEFExportedSymbol;
  556.  
  557.  
  558. /* -------------------------------------------------------------------------------------------    */
  559. /* The classAndName field of the PEFExportedSymbol type has the following bit field layout.        */
  560. /*                                                                                                 */
  561. /*                                                                       3                        */
  562. /*         0             7 8                                             1                        */
  563. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  564. /*      | symbol class  | offset of symbol name in loader string table  |                        */
  565. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        */
  566. /*        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        */
  567.  
  568.  
  569. enum {
  570.     kPEFExpSymClassShift        = 24,
  571.     kPEFExpSymNameOffsetMask    = 0x00FFFFFF,
  572.     kPEFExpSymMaxNameOffset        = 0x00FFFFFF                    /* 16,777,215 */
  573. };
  574.  
  575. #define PEFExportedSymbolClass(classAndName)        ((UInt8) ((classAndName) >> kPEFExpSymClassShift))
  576. #define PEFExportedSymbolNameOffset(classAndName)    ((classAndName) & kPEFExpSymNameOffsetMask)
  577.  
  578. #define PEFComposeExportedSymbol(class,nameOffset)        \
  579.             ( ( ((UInt32)(class)) << kPEFExpSymClassShift ) | ( (UInt32)(nameOffset) ) )
  580.  
  581. enum {
  582.                                                                 /* Negative section indices indicate pseudo-sections. */
  583.     kPEFAbsoluteExport            = -2,                            /* The symbol value is an absolute address. */
  584.     kPEFReexportedImport        = -3                            /* The symbol value is the index of a reexported import. */
  585. };
  586.  
  587.  
  588.  
  589. /* =========================================================================================== */
  590. /* Loader Relocations */
  591. /* ================== */
  592.  
  593.  
  594. /* -------------------------------------------------------------------------------------------    */
  595. /* The relocations for a section are defined by a sequence of instructions for an abstract        */
  596. /* machine that is specifically geared to performing relocations commonly needed for the "CFM"    */
  597. /* code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    */
  598. /* just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    */
  599. /* the operands in the first chunk, with other operands in following chunks.                    */
  600.  
  601.  
  602. typedef UInt16 PEFRelocChunk;
  603. struct PEFLoaderRelocationHeader {
  604.     UInt16                             sectionIndex;                /* Index of the section to be fixed up. */
  605.     UInt16                             reservedA;                    /* Reserved, must be zero. */
  606.     UInt32                             relocCount;                    /* Number of 16 bit relocation chunks. */
  607.     UInt32                             firstRelocOffset;            /* Offset of first relocation instruction. */
  608. };
  609. typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader;
  610.  
  611.  
  612. /* -------------------------------------------------------------------------------------------    */
  613. /* ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        */
  614. /* ! total number of bytes of relocation instructions.  While most relocation instructions are    */
  615. /* ! 16 bits long, some are longer so the number of complete relocation instructions may be        */
  616. /* ! less than the relocCount value.                                                            */
  617.  
  618.  
  619. /* ----------------------------------------------------------------------------------    */
  620. /* The PEFRelocField macro is a utility for extracting relocation instruction fields.    */
  621.  
  622.  
  623. #define PEFRFShift(offset,length)    (16 - (offset + length))
  624. #define PEFRFMask(length)            ((1 << length) - 1)
  625.  
  626. #define PEFRelocField(chunk,offset,length)    \
  627.             ( ( (chunk) >> (16 - ((offset) + (length))) ) & ((1 << (length)) - 1) )
  628.  
  629.  
  630. /* =========================================================================================== */
  631. /* Basic Relocation Opcodes */
  632. /* ------------------------ */
  633.  
  634.  
  635. /* ------------------------------------------------------------------------------------------    */
  636. /* The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    */
  637. /* are defined in terms of the most significant 7 bits of the first instruction chunk.  An        */
  638. /* instruction is decoded by using the most significant 7 bits as an index into the opcode        */
  639. /* table, which in turn contains appropriately masked forms of the most significant 7 bits.        */
  640. /* The macro PEFRelocBasicOpcode assumes a declaration of the form.                                */
  641. /*                                                                                                 */
  642. /*        UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = { PEFMaskedBasicOpcodes };    */
  643.  
  644.  
  645. enum {
  646.     kPEFRelocBasicOpcodeRange    = 128
  647. };
  648.  
  649. #define PEFRelocBasicOpcode(firstChunk) (kPEFRelocBasicOpcodes[(firstChunk)>>9])
  650.  
  651.  
  652. /* -------------------------------------------------------------------------------------------    */
  653. /* The relocation opcodes, clustered by major and minor groups.  The instructions within a        */
  654. /* cluster all have the same bit field layout.  The enumeration values use the high order 7        */
  655. /* bits of the relocation instruction.  Unused low order bits are set to zero.                    */
  656.  
  657.  
  658. enum {
  659.     kPEFRelocBySectDWithSkip    = 0x00,                            /* Binary: 00x_xxxx */
  660.     kPEFRelocBySectC            = 0x20,                            /* Binary: 010_0000, group is "RelocRun" */
  661.     kPEFRelocBySectD            = 0x21,                            /* Binary: 010_0001 */
  662.     kPEFRelocTVector12            = 0x22,                            /* Binary: 010_0010 */
  663.     kPEFRelocTVector8            = 0x23,                            /* Binary: 010_0011 */
  664.     kPEFRelocVTable8            = 0x24,                            /* Binary: 010_0100 */
  665.     kPEFRelocImportRun            = 0x25,                            /* Binary: 010_0101 */
  666.     kPEFRelocSmByImport            = 0x30,                            /* Binary: 011_0000, group is "RelocSmIndex" */
  667.     kPEFRelocSmSetSectC            = 0x31,                            /* Binary: 011_0001 */
  668.     kPEFRelocSmSetSectD            = 0x32,                            /* Binary: 011_0010 */
  669.     kPEFRelocSmBySection        = 0x33,                            /* Binary: 011_0011 */
  670.     kPEFRelocIncrPosition        = 0x40,                            /* Binary: 100_0xxx */
  671.     kPEFRelocSmRepeat            = 0x48,                            /* Binary: 100_1xxx */
  672.     kPEFRelocSetPosition        = 0x50,                            /* Binary: 101_000x */
  673.     kPEFRelocLgByImport            = 0x52,                            /* Binary: 101_001x */
  674.     kPEFRelocLgRepeat            = 0x58,                            /* Binary: 101_100x */
  675.     kPEFRelocLgSetOrBySection    = 0x5A,                            /* Binary: 101_101x */
  676.     kPEFRelocUndefinedOpcode    = 0xFF                            /* Used in masking table for all undefined values. */
  677. };
  678.  
  679.  
  680. /* ----------------------------------------------------------------------------    */
  681. /* The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode.    */
  682.  
  683.  
  684. enum {
  685.     kPEFRelocLgBySectionSubopcode = 0x00,                        /* Binary: 0000 */
  686.     kPEFRelocLgSetSectCSubopcode = 0x01,                        /* Binary: 0001 */
  687.     kPEFRelocLgSetSectDSubopcode = 0x02                            /* Binary: 0010 */
  688. };
  689.  
  690. #define PEFRelocLgSetOrBySubopcode(chunk) (((chunk) >> 6) & 0x0F)
  691.  
  692.  
  693. /* ------------------------------------------------------------------------------------------    */
  694. /* The initial values for the opcode "masking" table.  This has the enumeration values from        */
  695. /* above with appropriate replications for "don't care" bits.  It is almost certainly shorter    */
  696. /* and faster to look up the masked value in a table than to use a branch tree.                    */
  697.  
  698.  
  699. #define PEFMaskedBasicOpcodes                                                                                                                    \
  700.                                                                                                                                                 \
  701.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x00 .. 0x03 */    \
  702.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x04 .. 0x07 */    \
  703.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x08 .. 0x0B */    \
  704.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x0C .. 0x0F */    \
  705.                                                                                                                                                 \
  706.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x10 .. 0x13 */    \
  707.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x14 .. 0x17 */    \
  708.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x18 .. 0x1B */    \
  709.             kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    kPEFRelocBySectDWithSkip,    /* 0x1C .. 0x1F */    \
  710.                                                                                                                                                 \
  711.             kPEFRelocBySectC,            kPEFRelocBySectD,            kPEFRelocTVector12,            kPEFRelocTVector8,            /* 0x20 .. 0x23 */    \
  712.             kPEFRelocVTable8,            kPEFRelocImportRun,            kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x24 .. 0x27 */    \
  713.                                                                                                                                                 \
  714.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x28 .. 0x2B */    \
  715.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x2C .. 0x2F */    \
  716.                                                                                                                                                 \
  717.             kPEFRelocSmByImport,        kPEFRelocSmSetSectC,        kPEFRelocSmSetSectD,        kPEFRelocSmBySection,        /* 0x30 .. 0x33 */    \
  718.                                                                                                                                                 \
  719.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x34 .. 0x37 */    \
  720.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x38 .. 0x3B */    \
  721.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x3C .. 0x3F */    \
  722.                                                                                                                                                 \
  723.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x40 .. 0x43 */    \
  724.             kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        kPEFRelocIncrPosition,        /* 0x44 .. 0x47 */    \
  725.                                                                                                                                                 \
  726.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x48 .. 0x4B */    \
  727.             kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            kPEFRelocSmRepeat,            /* 0x4C .. 0x4F */    \
  728.                                                                                                                                                 \
  729.             kPEFRelocSetPosition,        kPEFRelocSetPosition,        kPEFRelocLgByImport,        kPEFRelocLgByImport,        /* 0x50 .. 0x53 */    \
  730.                                                                                                                                                 \
  731.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x54 .. 0x57 */    \
  732.                                                                                                                                                 \
  733.             kPEFRelocLgRepeat,            kPEFRelocLgRepeat,            kPEFRelocLgSetOrBySection,    kPEFRelocLgSetOrBySection,    /* 0x58 .. 0x5B */    \
  734.                                                                                                                                                 \
  735.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x5C .. 0x5F */    \
  736.                                                                                                                                                 \
  737.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x60 .. 0x63 */    \
  738.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x64 .. 0x67 */    \
  739.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x68 .. 0x6B */    \
  740.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x6C .. 0x6F */    \
  741.                                                                                                                                                 \
  742.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x70 .. 0x73 */    \
  743.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x74 .. 0x77 */    \
  744.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    /* 0x78 .. 0x7B */    \
  745.             kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode,    kPEFRelocUndefinedOpcode    /* 0x7C .. 0x7F */
  746.  
  747.  
  748. /* =========================================================================================== */
  749. /* RelocBySectDWithSkip Instruction */
  750. /* -------------------------------- */
  751.  
  752.  
  753. /* -------------------------------------------------------------------------------------------    */
  754. /* The "RelocBySectDWithSkip" instruction has the following bit field layout.                    */
  755. /*                                                                                                 */
  756. /*                             1         1                                                        */
  757. /*         0 1 2             9 0         5                                                        */
  758. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  759. /*        |0 0| skip count    | rel count |                                                        */
  760. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  761. /*        | 2 |<-- 8 bits --->|<--  6 --->|                                                        */
  762. /*                                                                                                 */
  763. /* ! Note that the stored skip count and reloc count are the actual values!                        */
  764.  
  765.  
  766. enum {
  767.     kPEFRelocWithSkipMaxSkipCount = 255,
  768.     kPEFRelocWithSkipMaxRelocCount = 63
  769. };
  770.  
  771. #define PEFRelocWithSkipSkipCount(chunk)    PEFRelocField ( (chunk), 2, 8 )
  772. #define PEFRelocWithSkipRelocCount(chunk)    PEFRelocField ( (chunk), 10, 6 )
  773.  
  774. #define PEFRelocComposeWithSkip(skipCount,relocCount)    \
  775.             ( 0x0000 | (((UInt16)(skipCount)) << 6) | ((UInt16)(relocCount)) )
  776.  
  777.  
  778. /* =========================================================================================== */
  779. /* RelocRun Group */
  780. /* -------------- */
  781.  
  782.  
  783. /* -------------------------------------------------------------------------------------------    */
  784. /* The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            */
  785. /* "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        */
  786. /* following bit field layout.                                                                    */
  787. /*                                                                                                 */
  788. /*                                       1                                                        */
  789. /*         0   2 3     6 7               5                                                        */
  790. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  791. /*        |0 1 0| subop.| run length      |                                                        */
  792. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  793. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                        */
  794. /*                                                                                                 */
  795. /* ! Note that the stored run length is the actual value minus 1, but the macros deal with the    */
  796. /* ! actual value!                                                                                */
  797.  
  798.  
  799. enum {
  800.     kPEFRelocRunMaxRunLength    = 512
  801. };
  802.  
  803. #define PEFRelocRunSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  804. #define PEFRelocRunRunLength(chunk)    (PEFRelocField ( (chunk), 7, 9 ) + 1)
  805.  
  806. #define PEFRelocComposeRun(subopcode,runLength)    \
  807.             ( 0x4000 | (((UInt16)(subopcode)) << 9) | ((UInt16)((runLength)-1)) )
  808.  
  809. #define PEFRelocComposeBySectC(runLength)        PEFRelocComposeRun ( 0, (runLength) )
  810. #define PEFRelocComposeBySectD(runLength)        PEFRelocComposeRun ( 1, (runLength) )
  811. #define PEFRelocComposeTVector12(runLength)        PEFRelocComposeRun ( 2, (runLength) )
  812. #define PEFRelocComposeTVector8(runLength)        PEFRelocComposeRun ( 3, (runLength) )
  813. #define PEFRelocComposeVTable8(runLength)        PEFRelocComposeRun ( 4, (runLength) )
  814. #define PEFRelocComposeImportRun(runLength)        PEFRelocComposeRun ( 5, (runLength) )
  815.  
  816.  
  817. /* =========================================================================================== */
  818. /* RelocSmIndex Group */
  819. /* ------------------ */
  820.  
  821.  
  822. /* ----------------------------------------------------------------------------------------    */
  823. /* The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                */
  824. /* "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    */
  825. /* field layout.                                                                            */
  826. /*                                                                                             */
  827. /*                                       1                                                    */
  828. /*         0   2 3     6 7               5                                                    */
  829. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  830. /*        |0 1 1| subop.| index           |                                                    */
  831. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    */
  832. /*        |  3  |<- 4 ->|<-- 9 bits ----->|                                                    */
  833. /*                                                                                             */
  834. /* ! Note that the stored index is the actual value!                                        */
  835.  
  836.  
  837. enum {
  838.     kPEFRelocSmIndexMaxIndex    = 511
  839. };
  840.  
  841. #define PEFRelocSmIndexSubopcode(chunk)    PEFRelocField ( (chunk), 3, 4 )
  842. #define PEFRelocSmIndexIndex(chunk)        PEFRelocField ( (chunk), 7, 9 )
  843.  
  844. #define PEFRelocComposeSmIndex(subopcode,index)    \
  845.             ( 0x6000 | (((UInt16)(subopcode)) << 9) | ((UInt16)(index)) )
  846.  
  847. #define PEFRelocComposeSmByImport(index)    PEFRelocComposeSmIndex ( 0, (index) )
  848. #define PEFRelocComposeSmSetSectC(index)    PEFRelocComposeSmIndex ( 1, (index) )
  849. #define PEFRelocComposeSmSetSectD(index)    PEFRelocComposeSmIndex ( 2, (index) )
  850. #define PEFRelocComposeSmBySection(index)    PEFRelocComposeSmIndex ( 3, (index) )
  851.  
  852.  
  853. /* =========================================================================================== */
  854. /* RelocIncrPosition Instruction */
  855. /* ----------------------------- */
  856.  
  857.  
  858. /* -------------------------------------------------------------------------------------------    */
  859. /* The "RelocIncrPosition" instruction has the following bit field layout.                        */
  860. /*                                                                                                 */
  861. /*                                       1                                                        */
  862. /*         0     3 4                     5                                                        */
  863. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  864. /*        |1 0 0 0| offset                |                                                        */
  865. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  866. /*        |<- 4 ->|<-- 12 bits ---------->|                                                        */
  867. /*                                                                                                 */
  868. /* ! Note that the stored offset is the actual value minus 1, but the macros deal with the        */
  869. /* ! actual value!                                                                                */
  870.  
  871.  
  872. enum {
  873.     kPEFRelocIncrPositionMaxOffset = 4096
  874. };
  875.  
  876. #define PEFRelocIncrPositionOffset(chunk)    (PEFRelocField ( (chunk), 4, 12 ) + 1)
  877.  
  878. #define PEFRelocComposeIncrPosition(offset)    \
  879.             ( 0x8000 | ((UInt16)((offset)-1)) )
  880.  
  881.  
  882. /* =========================================================================================== */
  883. /* RelocSmRepeat Instruction */
  884. /* ------------------------- */
  885.  
  886.  
  887. /* -------------------------------------------------------------------------------------------    */
  888. /* The "RelocSmRepeat" instruction has the following bit field layout.                            */
  889. /*                                                                                                 */
  890. /*                                       1                                                        */
  891. /*         0     3 4     7 8             5                                                        */
  892. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  893. /*        |1 0 0 1| chnks | repeat count  |                                                        */
  894. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        */
  895. /*        |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        */
  896. /*                                                                                                 */
  897. /* ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    */
  898. /* ! macros deal with the actual values!                                                        */
  899.  
  900.  
  901. enum {
  902.     kPEFRelocSmRepeatMaxChunkCount = 16,
  903.     kPEFRelocSmRepeatMaxRepeatCount = 256
  904. };
  905.  
  906. #define PEFRelocSmRepeatChunkCount(chunk)    (PEFRelocField ( (chunk), 4, 4 ) + 1)
  907. #define PEFRelocSmRepeatRepeatCount(chunk)    (PEFRelocField ( (chunk), 8, 8 ) + 1)
  908.  
  909. #define PEFRelocComposeSmRepeat(chunkCount,repeatCount)    \
  910.             ( 0x9000 | ((((UInt16)(chunkCount))-1) << 8) | (((UInt16)(repeatCount))-1) )
  911.  
  912.  
  913. /* =========================================================================================== */
  914. /* RelocSetPosition Instruction */
  915. /* ---------------------------- */
  916.  
  917.  
  918. /* -------------------------------------------------------------------------------------------    */
  919. /* The "RelocSetPosition" instruction has the following bit field layout.                        */
  920. /*                                                                                                 */
  921. /*                                       1                                   1                    */
  922. /*         0         5 6                 5     0                             5                    */
  923. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  924. /*        |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    */
  925. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  926. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  927. /*                                                                                                 */
  928. /* ! Note that the stored offset is the actual value!                                            */
  929.  
  930.  
  931. enum {
  932.     kPEFRelocSetPosMaxOffset    = 0x03FFFFFF                    /* 67,108,863 */
  933. };
  934.  
  935. #define PEFRelocSetPosOffsetHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  936.  
  937. #define PEFRelocSetPosFullOffset(firstChunk,secondChunk)    \
  938.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  939.  
  940. #define PEFRelocComposeSetPosition(fullOffset)    \
  941.             ( 0xA000 | ((UInt16) (((UInt32)(fullOffset)) >> 16) ) )
  942.  
  943.  
  944. /* =========================================================================================== */
  945. /* RelocLgByImport Instruction */
  946. /* --------------------------- */
  947.  
  948.  
  949. /* -------------------------------------------------------------------------------------------    */
  950. /* The "RelocLgByImport" instruction has the following bit field layout.                        */
  951. /*                                                                                                 */
  952. /*                                       1                                   1                    */
  953. /*         0         5 6                 5     0                             5                    */
  954. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  955. /*        |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    */
  956. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  957. /*        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    */
  958. /*                                                                                                 */
  959. /* ! Note that the stored offset is the actual value!                                            */
  960.  
  961.  
  962. enum {
  963.     kPEFRelocLgByImportMaxIndex    = 0x03FFFFFF                    /* 67,108,863 */
  964. };
  965.  
  966. #define PEFRelocLgByImportIndexHigh(chunk)    PEFRelocField ( (chunk), 6, 10 )
  967.  
  968. #define PEFRelocLgByImportFullIndex(firstChunk,secondChunk)    \
  969.             ( ((((UInt32)(firstChunk)) & 0x03FF) << 16) | ((UInt32)(secondChunk)) )
  970.  
  971. #define PEFRelocComposeLgByImport(fullIndex)    \
  972.             ( 0xA400 | ((UInt16) (((UInt32)(fullIndex)) >> 16) ) )
  973.  
  974.  
  975. /* =========================================================================================== */
  976. /* RelocLgRepeat Instruction */
  977. /* ------------------------- */
  978.  
  979.  
  980. /* -------------------------------------------------------------------------------------------    */
  981. /* The "RelocLgRepeat" instruction has the following bit field layout.                            */
  982. /*                                                                                                 */
  983. /*                             1         1                                   1                    */
  984. /*         0         5 6     9 0         5     0                             5                    */
  985. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  986. /*        |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    */
  987. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  988. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  989. /*                                                                                                 */
  990. /* ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        */
  991. /* ! the actual value!  The stored repeat count is the actual value!                            */
  992.  
  993.  
  994. enum {
  995.     kPEFRelocLgRepeatMaxChunkCount = 16,
  996.     kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF                /* 4,194,303 */
  997. };
  998.  
  999. #define PEFRelocLgRepeatChunkCount(chunk)        (PEFRelocField ( (chunk), 6, 4 ) + 1)
  1000. #define PEFRelocLgRepeatRepeatCountHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1001.  
  1002. #define PEFRelocLgRepeatFullRepeatCount(firstChunk,secondChunk)    \
  1003.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1004.  
  1005. #define PEFRelocComposeLgRepeat(chunkCount,fullRepeatCount)    \
  1006.             ( 0xB000 | ((((UInt16)(chunkCount))-1) << 6) | ((UInt16) (((UInt32)(fullRepeatCount)) >>16 ) ) )
  1007.  
  1008.  
  1009. /* =========================================================================================== */
  1010. /* RelocLgSetOrBySection Group */
  1011. /* --------------------------- */
  1012.  
  1013.  
  1014. /* -------------------------------------------------------------------------------------------    */
  1015. /* The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    */
  1016. /* "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        */
  1017. /* field layout.                                                                                */
  1018. /*                                                                                                 */
  1019. /*                             1         1                                   1                    */
  1020. /*         0         5 6     9 0         5     0                             5                    */
  1021. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1022. /*        |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    */
  1023. /*        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    */
  1024. /*        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    */
  1025. /*                                                                                                 */
  1026. /* ! Note that the stored index is the actual value!                                            */
  1027.  
  1028.  
  1029. enum {
  1030.     kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF                /* 4,194,303 */
  1031. };
  1032.  
  1033. #define PEFRelocLgSetOrBySectionSubopcode(chunk)    PEFRelocField ( (chunk), 6, 4 )
  1034. #define PEFRelocLgSetOrBySectionIndexHigh(chunk)    PEFRelocField ( (chunk), 10, 6 )
  1035.  
  1036. #define PEFRelocLgSetOrBySectionFullIndex(firstChunk,secondChunk)    \
  1037.             ( ((((UInt32)(firstChunk)) & 0x003F) << 16) | ((UInt32)(secondChunk)) )
  1038.  
  1039. #define PEFRelocComposeLgSetOrBySection(subopcode,fullIndex)    \
  1040.             ( 0xB400 | (((UInt16)(subopcode)) << 6) | ((UInt16) (((UInt32)(fullCount)) >> 16) ) )
  1041.  
  1042. #define PEFRelocComposeLgBySection(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x00, (fullIndex) )
  1043. #define PEFRelocComposeLgSetSectC(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x01, (fullIndex) )
  1044. #define PEFRelocComposeLgSetSectD(fullIndex)    PEFRelocComposeLgSetOrBySection ( 0x02, (fullIndex) )
  1045.  
  1046.  
  1047. /* =========================================================================================== */
  1048.  
  1049.  
  1050. #if PRAGMA_ALIGN_SUPPORTED
  1051. #pragma options align=reset
  1052. #endif
  1053.  
  1054. #if PRAGMA_IMPORT_SUPPORTED
  1055. #pragma import off
  1056. #endif
  1057.  
  1058. #ifdef __cplusplus
  1059. }
  1060. #endif
  1061.  
  1062. #endif /* __PEFBINARYFORMAT__ */
  1063.  
  1064.